#= require ./architect/version
#= require ./architect/worker

# Constants
@Architect.SUPPORT_WORKER = !!window.Worker
@Architect.WORKERS =
  proxy: { polyfill: @Architect.ProxyWorker, workerPath: '<%= Architect.worker_path("proxy") %>' }
  ajax:  { polyfill: @Architect.AjaxWorker,  workerPath: '<%= Architect.worker_path("ajax") %>'  }
  jsonp: { polyfill: @Architect.JSONPWorker, workerPath: '<%= Architect.worker_path("jsonp") %>' }

# Private methods
getWorkersPath = (type) ->
  return @Architect.WORKERS[type].workerPath unless @Architect.workersPath
  "#{@Architect.workersPath}/#{type}_worker.min.js"

spawnWorker = (type) ->
  return new @Architect.WORKERS[type].polyfill unless @Architect.SUPPORT_WORKER
  new Worker(getWorkersPath(type))

# Config
@Architect.setupWorkersPath = (path) =>
  @Architect.workersPath = path.replace(/\/$/, '')

# Short-lived workers
@Architect.work = (data, type, callback) ->
  worker = spawnWorker(type)
  worker.postMessage(data)
  worker.addEventListener 'message', (e) ->
    worker.terminate()
    callback(e.data)

@Architect.proxy = (data, callback) => @Architect.work(data, 'proxy', callback)
@Architect.ajax  = (url,  callback) => @Architect.work(url,  'ajax',  callback)
@Architect.jsonp = (url,  callback) => @Architect.work(url,  'jsonp', callback)

# Long-lived workers
jobs = {}
@Architect.workOn = (jobName, data, type, @workOnCallback) ->
  alreadySpawned = !!jobs[jobName]

  worker = jobs[jobName] ||= spawnWorker(type)
  worker.postMessage(data)

  return if alreadySpawned
  worker.addEventListener 'message', (e) =>
    @workOnCallback(e.data)

@Architect.endJob = (jobName) ->
  return unless worker = jobs[jobName]

  worker.terminate()
  delete jobs[jobName]

@Architect.proxyOn = (jobName, data, callback) => @Architect.workOn(jobName, data, 'proxy', callback)
@Architect.ajaxOn  = (jobName, url,  callback) => @Architect.workOn(jobName, url,  'ajax',  callback)
@Architect.jsonpOn = (jobName, url,  callback) => @Architect.workOn(jobName, url,  'jsonp', callback)

# Custom workers
@Architect.workFrom = (workerPath, data, fallback=null, callback) =>
  if callback is undefined
    callback = fallback
    fallback = null

  if @Architect.SUPPORT_WORKER
    worker = new Worker(workerPath)
    worker.postMessage(data)
    worker.addEventListener 'message', (e) ->
      worker.terminate()
      callback(e.data)
  else if fallback
    callback(fallback(data))
  else
    console.warn "No fallback provided for #{workerPath}"
